package com.goldsprite.projecttemplategenerator.testold;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.*;

public class PackageNameReplacer {

	public static void main(String[] args) {
		String oldPackageName = "com.goldsprite.xxx"; // 旧包名
		String newPackageName = "org.gdxapplication1"; // 新包名
		try {
//			replacePackageNames(new File("/sdcard/zzz/"), oldPackageName, newPackageName);
//			System.out.println("批量替换完成！");
		} catch (Exception e) {
			e.printStackTrace();
		}

		String oldProjectName = "project-template-generator";
		String newProjectName = "ProjectTemplateGenerator";
		// 获取当前项目目录下的 outputs 目录
		File currentDir = new File(System.getProperty("user.dir"));
		File outputsDir = new File(currentDir, "outputs");
		try {
			replaceProjectNames(outputsDir, oldProjectName, newProjectName);
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
	}

	public static void replacePackageNames(File directory, String oldPackageName, String newPackageName)
	throws IOException {
		// 替换文件内容中的包名
		replaceStrings(directory, oldPackageName, newPackageName);

		// 将包名拆分为目录路径
		String[] oldPackageParts = oldPackageName.split("\\.");
		String[] newPackageParts = newPackageName.split("\\.");

		// 查找根目录中包含 oldPackageParts[0] 的所有目录
		List<File> targetDirs = findTargetDirectories(directory, oldPackageName);
		for(File i : targetDirs) System.out.println("包含目录: "+i.getAbsolutePath());

		// 对每个符合条件的目录递归替换
		for (File targetDir : targetDirs) {
			replaceDirectories(targetDir, oldPackageParts, newPackageParts, 0, directory);
		}
	}

	private static List<File> findTargetDirectories(File directory, String targetPart) {
		List<File> result = new ArrayList<>();
		String[] targetParts = targetPart.split("\\.");
		if (!directory.isDirectory())
			return result;

		for (File file : directory.listFiles()) {
			if (file.isDirectory()) {
				// 如果目录名匹配，则添加到结果列表
				if (file.getName().equals(targetParts[0])) {
					result.add(file.getParentFile());
				}
				// 递归查找子目录
				else
					result.addAll(findTargetDirectories(file, targetPart));
			}
		}

		return result;
	}

	/*
	 - 增加支持对不同层级包名应用替换
	 - 实现思路：由递归重命名改为递归将目录下文件迁移到新包名层级下，并逐级检测旧包名目录为空则删除
	 */
	private static boolean replaceDirectories(File currentDir, String[] oldPackageParts, String[] newPackageParts, int level, File baseDir) throws IOException {
		if (level >= oldPackageParts.length) {
			return false;
		}

		// 当前级别目录名
		String targetDirName = oldPackageParts[level];
		File targetDir = new File(currentDir, targetDirName);

		if (targetDir.exists() && targetDir.isDirectory()) {
			// 递归处理子目录
			boolean childModified = replaceDirectories(targetDir, oldPackageParts, newPackageParts, level + 1, baseDir);
			//如果到达最后一级则将目录文件全部转移到新层级下
			if(level == oldPackageParts.length - 1){
				File oriDir = currentDir;
				for(int i=1;i<oldPackageParts.length;i++)
					oriDir = oriDir.getParentFile();
				File totalNewDir = new File(oriDir, String.join(File.separator, newPackageParts));
				if(!totalNewDir.exists()) totalNewDir.mkdirs();
				DirectoryMover.moveDirectory(targetDir, totalNewDir);
			}

			System.out.println("处理目录层级："+currentDir.getName()+", 是否已childModified"+ childModified+", targetDir: "+targetDir.getName()+"-文件数: "+(targetDir.list()==null?"null":targetDir.list().length)+", 当前层级等级: "+level);
			if(childModified) if(targetDir.list()==null || targetDir.list().length == 0) targetDir.delete();
			// 如果到达最后一级目录，或者子目录处理完毕，则检索目录是否为空并删除该目录
			if (level == oldPackageParts.length - 1 || childModified) {
				return true; // 当前目录已修改
			}
		}

		return false; // 未找到目标目录或未修改
	}

	public static void replaceStrings(File directory, String oldString, String newString) throws IOException {
		// 使用队列来遍历目录（支持深度遍历）
		Queue<File> filesQueue = new LinkedList<>();
		filesQueue.add(directory);

		while (!filesQueue.isEmpty()) {
			File currentFile = filesQueue.poll();

			if (currentFile.isDirectory()) {
				// 如果是目录，将子文件添加到队列中
				File[] children = currentFile.listFiles();
				if (children != null) {
					filesQueue.addAll(Arrays.asList(children));
				}
			}
			else if (currentFile.isFile()) {
				// 如果是文件，检查并替换内容
				replaceInFile(currentFile, oldString, newString);
			}
		}
	}

	private static void replaceInFile(File file, String oldText, String newText) throws IOException {
		// 读取文件内容
		String content;
		try (BufferedReader reader = new BufferedReader(
			new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8))) {
			StringBuilder builder = new StringBuilder();
			String line;
			while ((line = reader.readLine()) != null) {
				builder.append(line).append("\n");
			}
			content = builder.toString();
		}

		// 替换内容
		if (content.contains(oldText)) {
			content = content.replace(oldText, newText);

			// 写回文件
			try (BufferedWriter writer = new BufferedWriter(
				new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8))) {
				writer.write(content);
			}
			System.out.println("已替换: " + file.getPath());
		}
	}

	/**
	 * 替换指定目录下所有含有 ProjectName 的文件或目录名
	 * @param directory 目标目录
	 * @param oldProjectName 旧项目名
	 * @param newProjectName 新项目名
	 */
	public static void replaceProjectNames(File directory, String oldProjectName, String newProjectName) throws IOException {
		if (!directory.exists() || !directory.isDirectory()) {
			throw new IllegalArgumentException("目录不存在或不是有效目录: " + directory.getAbsolutePath());
		}

		System.out.println("开始替换项目名: " + oldProjectName + " -> " + newProjectName);
		System.out.println("目标目录: " + directory.getAbsolutePath());

		// 使用队列进行广度优先遍历
		Queue<File> queue = new LinkedList<>();
		queue.add(directory);

		int renamedCount = 0;

		while (!queue.isEmpty()) {
			File current = queue.poll();

			if (current.isDirectory()) {
				File[] children = current.listFiles();
				if (children != null && children.length > 0) {
					// 先处理子文件和目录（避免重命名后路径变化）
					for (File child : children) {
						queue.add(child);
					}

					// 检查当前目录名是否需要重命名
					if (current.getName().contains(oldProjectName)) {
						String newName = current.getName().replace(oldProjectName, newProjectName);
						File newFile = new File(current.getParent(), newName);

						if (!current.equals(directory)) { // 避免重命名根目录
							if (current.renameTo(newFile)) {
								System.out.println("重命名目录: " + current.getName() + " -> " + newName);
								renamedCount++;
							} else {
								System.err.println("重命名目录失败: " + current.getAbsolutePath());
							}
						}
					}
				}
			} else {
				// 处理文件名
				if (current.getName().contains(oldProjectName)) {
					String newName = current.getName().replace(oldProjectName, newProjectName);
					File newFile = new File(current.getParent(), newName);

					if (current.renameTo(newFile)) {
						System.out.println("重命名文件: " + current.getName() + " -> " + newName);
						renamedCount++;
					} else {
						System.err.println("重命名文件失败: " + current.getAbsolutePath());
					}
				}
			}
		}

		System.out.println("项目名替换完成，共重命名 " + renamedCount + " 个文件/目录");
	}
}

